<template>
  <div class="knowledge-upsert">
    <div class="knowledge-container">
      <div class="sidebar">
        <button
          class="action-button"
          :class="{ active: activeTab === 'add' }"
          @click="activeTab = 'add'"
        >
          新增数据
        </button>
        <button
          class="action-button"
          :class="{ active: activeTab === 'update' }"
          @click="activeTab = 'update'"
        >
          更新数据
        </button>
      </div>

      <div class="content-container">
        <div v-if="showToast" class="toast-notification">
          {{ toastMessage }}
        </div>

        <div class="upload-container">
          <h2>{{ activeTab === 'add' ? '添加知识条目' : '更新知识条目' }}</h2>

          <div class="format-requirements">
            <div class="format-header">
              <h3>JSON格式模板</h3>
              <button class="copy-button" @click="copyTemplate" title="复制模板">
                <DocumentDuplicateIcon class="copy-icon" />
              </button>
            </div>
            <pre class="format-example">{{
              activeTab === 'add' ? addTemplate : updateTemplate
            }}</pre>
          </div>

          <div class="upload-area">
            <input
              type="file"
              id="jsonFile"
              accept=".json"
              @change="handleFileChange"
              :disabled="isProcessing"
            />
            <label for="jsonFile" class="upload-button">
              <span v-if="!selectedFile">选择JSON文件</span>
              <span v-else>{{ selectedFile.name }}</span>
            </label>

            <button
              class="analyze-button"
              @click="submitData"
              :disabled="!selectedFile || isProcessing"
            >
              {{ isProcessing ? '处理中...' : activeTab === 'add' ? '新增' : '更新' }}
            </button>
          </div>

          <div v-if="progress > 0" class="progress-container">
            <div class="progress-bar">
              <div class="progress" :style="{ width: `${progress}%` }"></div>
            </div>
            <span class="progress-text">{{ progress }}%</span>
          </div>

          <div v-if="responseData" class="result-container">
            <div class="result-preview">
              <div class="result-header">
                <h3>处理结果</h3>
                <button class="copy-button" @click="copyResult" title="复制结果">
                  <DocumentDuplicateIcon class="copy-icon" />
                </button>
              </div>
              <pre>{{ responseData }}</pre>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { DocumentDuplicateIcon } from '@heroicons/vue/24/outline'

const activeTab = ref('add')
const selectedFile = ref(null)
const isProcessing = ref(false)
const progress = ref(0)
const responseData = ref(null)
// cancelToken is a placeholder for a real cancellation mechanism.
const cancelToken = ref(false);

const addTemplate = `[
  {
    "matchKey": "西甲_皇家马德里_vs_巴塞罗那_2025-05-10",
    "league": "西甲",
    "homeTeam": "皇家马德里",
    "awayTeam": "巴塞罗那",
    "content": "国家德比再次上演，皇马本赛季表现强势，中场控制力和前场攻击力均为顶级。巴萨在重建中，年轻球员需要更多时间成长，但进攻端依然有威胁。历史交锋火星四溅，主场优势对皇马有利。关键看点是贝林厄姆与加维的中场对决。"
  },
  {
    "matchKey": "英超_曼城_vs_利物浦_2025-05-11",
    "league": "英超",
    "homeTeam": "曼城",
    "awayTeam": "利物浦",
    "content": "英超争冠关键战役。曼城拥有强大的阵容深度和控球能力，哈兰德是终结利器。利物浦的高位压迫和快速反击极具威胁，萨拉赫状态决定球队上限。两队主帅瓜迪奥拉和克洛普（假设仍在）的战术博弈是最大看点。预计将是一场快节奏、高强度的对攻大战。"
  }
]`

const updateTemplate = `{
  "id": 3,
  "matchKey": "中超_上海海港_vs_天津津门虎_2024-06-14",
  "league": "中超联赛",
  "homeTeam": "上海海港",
  "awayTeam": "天津津门虎",
  "content": "上海海港近期状态稳定，攻击线多点开花..."
}`

const handleFileChange = (event) => {
  const file = event.target.files[0]
  if (file && file.type === 'application/json') {
    selectedFile.value = file
  } else {
    // 使用模态框代替 alert
    showNotification('请选择有效的JSON文件')
    event.target.value = ''
  }
}

const submitData = async () => {
  if (!selectedFile.value) return

  isProcessing.value = true
  progress.value = 0

  try {
    const fileContent = await new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => resolve(reader.result)
      reader.onerror = reject
      reader.readAsText(selectedFile.value)
    })

    const jsonData = JSON.parse(fileContent)
    
    const jsonListLength = JSON.parse(fileContent).length
    // 模拟进度条
    const interval = setInterval(() => {
      if (cancelToken.value) {
        clearInterval(interval)
        return
      }
      const totalTimeInSeconds = jsonListLength * 90
      const intervalTime = 1000
      const incrementPerInterval = (100 / totalTimeInSeconds) * (intervalTime / 1000)
      if (progress.value < 100) {
        progress.value += incrementPerInterval
        progress.value = Math.min(parseFloat(progress.value.toFixed(2)), 100)
      }
    }, 700)

    const endpoint = activeTab.value === 'add' ? '/add' : `/update/${jsonData.id || ''}`

    const method = activeTab.value === 'add' ? 'POST' : 'PUT'
    const response = await fetch(`/knowledge${endpoint}`, {
      method,
      headers: {
        'Content-Type': 'application/json',
      },
      body: fileContent,
    })

    clearInterval(interval)
    progress.value = 100

    if (response.ok) {
      const data = await response.json()
      responseData.value = JSON.stringify(data, null, 2)
      showNotification(activeTab.value === 'add' ? '添加成功' : '更新成功')
    } else {
      const error = await response.text()
      throw new Error(error || (activeTab.value === 'add' ? '添加失败' : '更新失败'))
    }
  } catch (error) {
    console.error('处理错误:', error)
    // 使用模态框代替 alert
    showNotification(error.message)
  } finally {
    isProcessing.value = false
  }
}

const toastMessage = ref('')
const showToast = ref(false)

const showNotification = (message) => {
  toastMessage.value = message
  showToast.value = true
  setTimeout(() => {
    showToast.value = false
  }, 1000)
}

const copyToClipboard = (text, successMessage, errorMessage) => {
  // 检查 navigator.clipboard 是否可用
  if (navigator.clipboard && navigator.clipboard.writeText) {
    navigator.clipboard
      .writeText(text)
      .then(() => showNotification(successMessage))
      .catch(() => {
        console.error('Failed to copy using navigator.clipboard. Trying fallback.')
        fallbackCopyToClipboard(text, successMessage, errorMessage)
      })
  } else {
    // 降级使用 document.execCommand
    fallbackCopyToClipboard(text, successMessage, errorMessage)
  }
}

const fallbackCopyToClipboard = (text, successMessage, errorMessage) => {
  const textarea = document.createElement('textarea')
  textarea.value = text
  textarea.style.position = 'fixed' // 避免滚动
  textarea.style.opacity = 0
  document.body.appendChild(textarea)
  textarea.focus()
  textarea.select()
  try {
    const successful = document.execCommand('copy')
    const message = successful ? successMessage : errorMessage
    showNotification(message)
  } catch (err) {
    console.error('Fallback copy failed', err)
    showNotification(errorMessage)
  } finally {
    document.body.removeChild(textarea)
  }
}

const copyTemplate = () => {
  const template = activeTab.value === 'add' ? addTemplate : updateTemplate
  copyToClipboard(template, '模板已复制', '复制失败')
}

const copyResult = () => {
  if (!responseData.value) return
  copyToClipboard(responseData.value, '结果已复制', '复制失败')
}
</script>

<style scoped lang="scss">
.knowledge-upsert {
  position: fixed;
  top: 64px;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  background: var(--bg-color);
  overflow: auto;
  z-index: 1;

  .knowledge-container {
    display: flex;
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem;
    gap: 2rem;
    align-items: stretch;
  }

  .sidebar {
    width: 200px;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem;
    background: white;
    border-radius: 12px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    height: 100%;

    .action-button {
      padding: 0.75rem 1rem;
      background: #f8f9fa;
      border: none;
      border-radius: 8px;
      cursor: pointer;
      transition: all 0.2s;
      text-align: left;

      &:hover {
        background: #e9ecef;
      }

      &.active {
        background: #007cf0;
        color: white;
      }
    }
  }

  .content-container {
    display: flex;
    flex-direction: column;
    flex: 1;
  }

  .upload-container {
    flex: 1;
    background: white;
    border-radius: 12px;
    padding: 2rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    width: 100%;

    h2 {
      text-align: center;
      color: #333;
      margin-bottom: 2rem;
      font-size: 1.8rem;
    }

    .format-requirements {
      margin-bottom: 2rem;
      background: #f8f9fa;
      padding: 1rem;
      border-radius: 8px;
      border: 1px solid #e9ecef;

      .format-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 0.5rem;

        h3 {
          margin: 0;
          color: #495057;
          font-size: 1.1rem;
        }

        .copy-button {
          background: none;
          border: none;
          cursor: pointer;
          color: #495057;
          padding: 0;

          .copy-icon {
            width: 1.2rem;
            height: 1.2rem;
          }
        }
      }

      .format-example {
        background: #f1f3f5;
        padding: 1rem;
        border-radius: 4px;
        overflow-x: auto;
        font-family: 'Courier New', monospace;
        color: #495057;
        white-space: pre-wrap;
      }
    }

    .upload-area {
      display: flex;
      gap: 1rem;
      margin-bottom: 2rem;
      align-items: center;

      input[type='file'] {
        display: none;
      }

      .upload-button {
        flex: 1;
        padding: 0.75rem 1rem;
        background: #f8f9fa;
        border: 1px dashed #adb5bd;
        border-radius: 8px;
        text-align: center;
        cursor: pointer;
        transition: all 0.2s;

        &:hover {
          background: #e9ecef;
          border-color: #6c757d;
        }
      }

      .analyze-button {
        padding: 0.75rem 1.5rem;
        background: #007cf0;
        color: white;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        transition: background-color 0.2s;

        &:disabled {
          background: #adb5bd;
          cursor: not-allowed;
        }

        &:hover:not(:disabled) {
          background: #005bb5;
        }
      }
    }

    .progress-container {
      display: flex;
      align-items: center;
      gap: 1rem;
      margin-bottom: 2rem;

      .progress-bar {
        flex: 1;
        height: 8px;
        background: #e9ecef;
        border-radius: 4px;

        .progress {
          height: 100%;
          background: #007cf0;
          border-radius: 4px;
          transition: width 0.4s ease;
        }
      }

      .progress-text {
        font-size: 0.9rem;
        color: #495057;
      }
    }

    .result-container {
      border: 1px solid #e9ecef;
      border-radius: 8px;
      padding: 1rem;

      .result-preview {
        .result-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 0.5rem;

          h3 {
            margin: 0;
            color: #495057;
            font-size: 1.1rem;
          }
        }

        pre {
          background: #f1f3f5;
          padding: 1rem;
          border-radius: 4px;
          white-space: pre-wrap;
          word-break: break-all;
          max-height: 300px;
          overflow-y: auto;
          font-family: 'Courier New', monospace;
        }
      }
    }
  }
}

.toast-notification {
  position: fixed;
  top: 8%;
  left: 50%;
  transform: translateX(-50%);
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 12px 24px;
  border-radius: 4px;
  z-index: 1000;
  animation: fadeInOut 1s ease-in-out forwards;
}

@keyframes fadeInOut {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(20px);
  }

  20% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }

  80% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }

  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
  }
}

// Dark mode styles
.dark {
  .knowledge-upsert {
    background: #1a202c;

    .knowledge-container {
      .sidebar {
        background: #2d3748;
        box-shadow: none;

        .action-button {
          background: #4a5568;
          color: #e2e8f0;

          &:hover {
            background: #2d3748;
          }

          &.active {
            background: #007cf0;
            color: white;
          }
        }
      }

      .content-container {
        .upload-container {
          background: #2d3748;
          box-shadow: none;

          h2 {
            color: #e2e8f0;
          }

          .format-requirements {
            background: #4a5568;
            border-color: #4a5568;

            .format-header {
              h3 {
                color: #e2e8f0;
              }

              .copy-button {
                color: #e2e8f0;
              }
            }

            .format-example {
              background: #2d3748;
              color: #e2e8f0;
            }
          }

          .upload-area {
            .upload-button {
              background: #4a5568;
              border-color: #4a5568;
              color: #e2e8f0;

              &:hover {
                background: #2d3748;
              }
            }

            .analyze-button {
              background: #007cf0;
              color: white;

              &:disabled {
                background: #4a5568;
                color: #e2e8f0;
              }
            }
          }

          .progress-container {
            .progress-bar {
              background: #4a5568;
            }

            .progress-text {
              color: #e2e8f0;
            }
          }

          .result-container {
            border-color: #4a5568;

            .result-preview {
              h3 {
                color: #e2e8f0;
              }

              pre {
                background: #2d3748;
                color: #e2e8f0;
              }
            }
          }
        }
      }
    }
  }

  .toast-notification {
    background-color: rgba(255, 255, 255, 0.9);
    color: #333;
  }
}
</style>